﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.Optimization;

using MiniSched.Orm.Initialization;
using MiniSched.Web.Security.Initialization;
using MiniSched.Web.Abstractions;
using MiniSched.Logging;
using MiniSched.Logging.Log4Net;

namespace MiniSched.Web {

    public class MvcApplication : HttpApplication {

        static MvcApplication() {
            MiniSchedLogFactory.Default = new Log4NetLogFactory();
        }

        internal AreaRegistrationAbstraction AreaRegistration {
            get {
                if (null == _AreaRegistration) _AreaRegistration = AreaRegistrationAbstraction.Default;
                return _AreaRegistration;
            }
            set {
                if (null == value) throw new ArgumentNullException("AreaRegistration");
                _AreaRegistration = value;
            }
        }
        private AreaRegistrationAbstraction _AreaRegistration;

        internal RouteTableAbstraction RouteTable {
            get {
                if (null == _RouteTable) _RouteTable = RouteTableAbstraction.Default;
                return _RouteTable;
            }
            set {
                if (null == value) throw new ArgumentNullException("RouteTable");
                _RouteTable = value;
            }
        }
        private RouteTableAbstraction _RouteTable;

        protected void Application_Start() {

            ContextInitializer.InitializeContext();
            SecurityInitializer.InitializeSecurity();

            AreaRegistration.RegisterAllAreas();

            var routes = RouteTable.Routes;
            if (routes == null) throw new InvalidOperationException("The routes cannot be null.");

            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
            );

            var bundles = BundleTable.Bundles;
            bundles.Add(new ScriptBundle("~/bundles/jquery/js").Include(
                "~/Scripts/jquery-{version}.js"
            ));

            bundles.Add(new ScriptBundle("~/bundles/underscore/js").Include(
                "~/Scripts/underscore.js"
            ));

            bundles.Add(new ScriptBundle("~/bundles/knockout/js").Include(
                "~/Scripts/knockout-{version}.js",
                "~/Scripts/knockout.validation.js"
            ));

            bundles.Add(new ScriptBundle("~/bundles/site/js").Include(
                "~/Scripts/Site/miniSched.js",
                "~/Scripts/Site/Api/jsonApiClient.js",
                "~/Scripts/Site/Api/apiClient.js",
                "~/Scripts/Site/Api/entityApiClient.js",
                "~/Scripts/Site/Api/organizationApiClient.js",
                "~/Scripts/Site/Api/userProfileApiClient.js",
                "~/Scripts/Site/Api/volunteerApiClient.js",
                "~/Scripts/Site/Models/model.js",
                "~/Scripts/Site/Models/entityModel.js",
                "~/Scripts/Site/Models/organizationModel.js",
                "~/Scripts/Site/Models/userProfileModel.js",
                "~/Scripts/Site/Models/volunteerModel.js"
            ));
        }

        public MiniSchedContextInitializer ContextInitializer {
            get {
                if (null == _ContextInitializer) _ContextInitializer = new MiniSchedContextInitializer();
                return _ContextInitializer;
            }
            set {
                if (null == value) throw new ArgumentNullException("ContextInitializer");
                _ContextInitializer = value;
            }
        }
        private MiniSchedContextInitializer _ContextInitializer;

        public MiniSchedSecurityInitializer SecurityInitializer {
            get {
                if (null == _SecurityInitializer) _SecurityInitializer = new MiniSchedSecurityInitializer();
                return _SecurityInitializer;
            }
            set {
                if (null == value) throw new ArgumentNullException("SecurityInitializer");
                _SecurityInitializer = value;
            }
        }
        private MiniSchedSecurityInitializer _SecurityInitializer;
    }
}
